package com.campus.backend.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.backend.bean.notice.CreateNoticeBean;
import com.campus.backend.bean.notice.NoticeQueryParam;
import com.campus.backend.bean.notice.UpdateNoticeBean;
import com.campus.backend.entity.Notice;
import com.campus.backend.mapper.NoticeMapper;
import com.campus.backend.vo.notice.NoticeVo;
import com.campus.common.bean.common.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 公告表 服务实现类
 * </p>
 *
 * @author ZhaoYuJie
 * @since 2025-07-15
 */
@Service
public class NoticeService extends ServiceImpl<NoticeMapper, Notice> {

    /**
     * 分页查询公告列表
     *
     * @param param 查询参数
     * @return 分页结果
     */
    public PageInfo<NoticeVo> getNoticeListPage(NoticeQueryParam param) {
        PageHelper.startPage(param.getPageNo(), param.getPageSize());
        PageInfo<Notice> pageInfo = new PageInfo<>(getNoticeList(param));

        // 转换为VO对象
        List<NoticeVo> voList = pageInfo.getList().stream().map(notice -> {
            NoticeVo vo = new NoticeVo();
            BeanUtil.copyProperties(notice, vo);
            
            // 设置目标类型名称
            switch (notice.getTargetType()) {
                case 0:
                    vo.setTargetTypeName("全部端");
                    break;
                case 1:
                    vo.setTargetTypeName("顾客端");
                    break;
                case 2:
                    vo.setTargetTypeName("商家端");
                    break;
                case 3:
                    vo.setTargetTypeName("配送端");
                    break;
                default:
                    vo.setTargetTypeName("未知类型");
                    break;
            }
            
            // 设置优先级名称
            switch (notice.getPriority()) {
                case 0:
                    vo.setPriorityName("普通");
                    break;
                case 1:
                    vo.setPriorityName("重要");
                    break;
                case 2:
                    vo.setPriorityName("紧急");
                    break;
                default:
                    vo.setPriorityName("未知优先级");
                    break;
            }
            
            // 设置状态名称
            vo.setStatusName(notice.getStatus() == 1 ? "启用" : "禁用");
            
            // 设置置顶名称
            vo.setIsTopName(notice.getIsTop() == 1 ? "是" : "否");
            
            return vo;
        }).collect(java.util.stream.Collectors.toList());

        return PageUtil.convertPageInfo(pageInfo, voList);
    }

    /**
     * 查询公告列表
     *
     * @param param 查询参数
     * @return 公告列表
     */
    private List<Notice> getNoticeList(NoticeQueryParam param) {
        LambdaQueryWrapper<Notice> queryWrapper = new LambdaQueryWrapper<>();
        
        if (param.getTargetType() != null) {
            queryWrapper.eq(Notice::getTargetType, param.getTargetType());
        }
        
        if (param.getPriority() != null) {
            queryWrapper.eq(Notice::getPriority, param.getPriority());
        }
        
        if (param.getStatus() != null) {
            queryWrapper.eq(Notice::getStatus, param.getStatus());
        }
        
        if (param.getIsTop() != null) {
            queryWrapper.eq(Notice::getIsTop, param.getIsTop());
        }
        
        if (StringUtils.hasText(param.getTitle())) {
            queryWrapper.like(Notice::getTitle, param.getTitle());
        }
        
        // 逻辑删除过滤由@TableLogic自动处理，无需手动添加条件
        
        // 排序：置顶优先，然后按优先级降序，最后按创建时间降序
        queryWrapper.orderByDesc(Notice::getIsTop, Notice::getPriority, Notice::getCreateTime);
        
        return this.list(queryWrapper);
    }

    /**
     * 根据ID获取公告详情
     *
     * @param noticeId 公告ID
     * @return 公告VO
     */
    public NoticeVo getNoticeById(Integer noticeId) {
        Notice notice = this.getById(noticeId);
        if (notice == null) {
            throw new RuntimeException("公告不存在");
        }
        
        NoticeVo vo = new NoticeVo();
        BeanUtil.copyProperties(notice, vo);
        
        // 设置目标类型名称
        switch (notice.getTargetType()) {
            case 0:
                vo.setTargetTypeName("全部端");
                break;
            case 1:
                vo.setTargetTypeName("顾客端");
                break;
            case 2:
                vo.setTargetTypeName("商家端");
                break;
            case 3:
                vo.setTargetTypeName("配送端");
                break;
            default:
                vo.setTargetTypeName("未知类型");
                break;
        }
        
        // 设置优先级名称
        switch (notice.getPriority()) {
            case 0:
                vo.setPriorityName("普通");
                break;
            case 1:
                vo.setPriorityName("重要");
                break;
            case 2:
                vo.setPriorityName("紧急");
                break;
            default:
                vo.setPriorityName("未知优先级");
                break;
        }
        
        // 设置状态名称
        vo.setStatusName(notice.getStatus() == 1 ? "启用" : "禁用");
        
        // 设置置顶名称
        vo.setIsTopName(notice.getIsTop() == 1 ? "是" : "否");
        
        return vo;
    }

    /**
     * 创建公告
     *
     * @param createNoticeBean 公告信息
     * @return 公告ID
     */
    public Integer createNotice(CreateNoticeBean createNoticeBean) {
        Notice notice = new Notice();
        BeanUtil.copyProperties(createNoticeBean, notice);
        
        // 设置默认值
        if (notice.getPriority() == null) {
            notice.setPriority(0); // 默认普通优先级
        }
        if (notice.getStatus() == null) {
            notice.setStatus(0); // 默认禁用状态
        }
        if (notice.getIsTop() == null) {
            notice.setIsTop(0); // 默认不置顶
        }
        
        notice.setViewCount(0); // 初始浏览量为0
        notice.setCreateTime(LocalDateTime.now());
        notice.setUpdateTime(LocalDateTime.now());
        
        this.save(notice);
        return notice.getId();
    }

    /**
     * 更新公告
     *
     * @param updateNoticeBean 公告信息
     */
    public void updateNotice(UpdateNoticeBean updateNoticeBean) {
        Notice existNotice = this.getById(updateNoticeBean.getId());
        if (existNotice == null) {
            throw new RuntimeException("公告不存在");
        }
        
        Notice notice = new Notice();
        BeanUtil.copyProperties(updateNoticeBean, notice);
        notice.setUpdateTime(LocalDateTime.now());
        
        this.updateById(notice);
    }

    /**
     * 删除公告（逻辑删除）
     *
     * @param noticeId 公告ID
     */
    public void deleteNotice(Integer noticeId) {
        Notice notice = this.getById(noticeId);
        if (notice == null) {
            throw new RuntimeException("公告不存在");
        }
        
        // 使用MyBatis Plus的逻辑删除，会自动设置del_flag
        this.removeById(noticeId);
    }

    /**
     * 批量删除公告（逻辑删除）
     *
     * @param noticeIds 公告ID列表
     */
    public void batchDeleteNotice(List<Integer> noticeIds) {
        if (noticeIds == null || noticeIds.isEmpty()) {
            throw new RuntimeException("请选择要删除的公告");
        }
        
        // 使用MyBatis Plus的逻辑删除，会自动设置del_flag
        this.removeByIds(noticeIds);
    }

    /**
     * 更新公告状态
     *
     * @param noticeId 公告ID
     * @param status 状态
     */
    public void updateNoticeStatus(Integer noticeId, Integer status) {
        Notice notice = this.getById(noticeId);
        if (notice == null) {
            throw new RuntimeException("公告不存在");
        }
        
        LambdaUpdateWrapper<Notice> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Notice::getId, noticeId)
                .set(Notice::getStatus, status)
                .set(Notice::getUpdateTime, LocalDateTime.now());
        
        this.update(updateWrapper);
    }

    /**
     * 更新公告置顶状态
     *
     * @param noticeId 公告ID
     * @param isTop 是否置顶
     */
    public void updateNoticeTop(Integer noticeId, Integer isTop) {
        Notice notice = this.getById(noticeId);
        if (notice == null) {
            throw new RuntimeException("公告不存在");
        }
        
        LambdaUpdateWrapper<Notice> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Notice::getId, noticeId)
                .set(Notice::getIsTop, isTop)
                .set(Notice::getUpdateTime, LocalDateTime.now());
        
        this.update(updateWrapper);
    }
}
